package com.ody.util.code;

import com.odianyun.util.io.FileUtils;
import com.ody.util.code.generator.ICodeGenerator;
import java.io.File;
import java.util.Map;
import javax.swing.*;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.ResourceUtils;

public class Main {

	public static AbstractApplicationContext xmlContext() {
		return new ClassPathXmlApplicationContext(new String[] { "classpath*:spring/applicationContext.xml" });
	}

	public static AbstractApplicationContext annotationContext(String propertiesFilePath, boolean refresh,
			boolean runConfigWithGui, boolean runModelWithGui) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();

		ctx.registerBeanDefinition("codeConfiguration", getCodeConfiguration(propertiesFilePath, runConfigWithGui, runModelWithGui));

		if (refresh) {
			ctx.refresh();
		}

		return ctx;
	}

	private static BeanDefinition getCodeConfiguration(String propertiesFilePath, boolean runConfigWithGui, boolean runModelWithGui) {
		BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CodeConfiguration.class);
		builder.addPropertyValue("propertiesFilePath", propertiesFilePath);
		builder.addPropertyValue("runConfigWithGui", runConfigWithGui);
        builder.addPropertyValue("runModelWithGui", runModelWithGui);

        return builder.getBeanDefinition();
	}

	public static void generate(AbstractApplicationContext ctx, boolean runConfigWithGui, boolean runWithGui) throws Exception {
		Map<String, ICodeGenerator> map = ctx.getBeansOfType(ICodeGenerator.class);
		if (runWithGui) {
			runGui(map, ctx, runConfigWithGui);
		} else {
			doGenerate(map);
		}

		ctx.close();
	}

	private static void runGui(Map<String, ICodeGenerator> map, AbstractApplicationContext ctx, boolean runConfigWithGui) throws Exception {
        GeneratorGui gui = new GeneratorGui();
        gui.setRenderModelProviderGui(!runConfigWithGui);
		gui.open(map, ctx);
	}

	private static void doGenerate(Map<String, ICodeGenerator> map) throws Exception {
		for (String key : map.keySet()) {
			System.out.println(key + " is start...");
			ICodeGenerator generator = map.get(key);
			generator.generate();
			System.out.println(key + " is done");
		}
	}

	private static String getParentPath(String configPath) throws Exception {
		File file = ResourceUtils.getFile(configPath);
		if (file == null) {
			
		}
		String path = file.getPath();
		
		path = FileUtils.getParent(path);
		
		return path;
	}

	public static void main(String[] args) throws Exception {
		String theme = Const.THEME;
		String propertiesFilePath = Const.CONFIG_PATH;

		boolean runWithGui = false;
        boolean runConfigWithGui = false;
        boolean runModelWithGui = false;
		boolean debug = false;
		boolean update = false;
		String checkUrl = Const.DEFAULT_CHECK_URL;
		
		if (args.length > 0) {
			for (String arg : args) {
				if ("-v".equals(arg) || "--version".equals(arg)) {
					System.out.println("当前版本：" + Const.VERSION);
				} else if ("-debug".equals(arg)) {
					System.out.println("debug mode");
					debug = true;
				} else if ("-gui".equals(arg)) {
					runWithGui = true;
                    runConfigWithGui = true;
                    runModelWithGui = true;
				} else if ("-update".equals(arg)) {
					update = true;
				} else if (arg.startsWith("--updateUrl=")) {
                    checkUrl = arg.substring("--updateUrl=".length());
                } else if (arg.startsWith("--theme=")) {
					theme = arg.substring("--theme=".length());
				} else if (arg.startsWith("--theme.list=")) {
					System.setProperty("theme.list", arg.substring("--theme.list=".length()));
				} else {
					propertiesFilePath = arg;
				}
			}
		}
		
		propertiesFilePath = propertiesFilePath.replace("${theme}", theme);
		
		String path = getParentPath(propertiesFilePath);
		
		if (update) {
			boolean isUpdated = Updater.update(path, checkUrl, Const.VERSION, debug);
			if (isUpdated) {
				if (debug) {
					if (runWithGui) {
						JOptionPane.showMessageDialog(null, "更新成功");
					} else {
						System.out.println("更新成功");
					}
				}
				Runtime.getRuntime().exec(new File(new File(path), "run.bat").getPath());
				return;
			} else if (debug) {
				if (runWithGui) {
					JOptionPane.showMessageDialog(null, "当前已是最新版本");
				} else {
					System.out.println("当前已是最新版本");
				}
			}
		}
		
        generate(annotationContext(propertiesFilePath, true, runConfigWithGui, runModelWithGui), runConfigWithGui, runWithGui);
	}

}
